package com.zhiche.lisa.bms.service.psup.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiche.lisa.bms.dao.mapper.psup.PsupTraditionPriceMapper;
import com.zhiche.lisa.bms.dao.model.psup.PsupTraditionPrice;
import com.zhiche.lisa.bms.enums.SdCommonEnum;
import com.zhiche.lisa.bms.pojo.dto.util.LspFleetDTO;
import com.zhiche.lisa.bms.pojo.vo.psup.PsupTraditionPriceVO;
import com.zhiche.lisa.bms.service.psup.PsupTraditionPriceService;
import com.zhiche.lisa.bms.service.utils.LspUtil;
import com.zhiche.lisa.bms.utils.ToolCommonUtils;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.Account.AccountUtil;
import com.zhiche.lisa.core.utils.Account.JwtAccountVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 人送传统价格管理 服务实现类
 * </p>
 *
 * @author linbao
 * @since 2019-06-18
 */
@Service
@Slf4j
public class PsupTraditionPriceServiceImpl extends ServiceImpl<PsupTraditionPriceMapper, PsupTraditionPrice> implements PsupTraditionPriceService {

    @Autowired
    private LspUtil lspUtil;

    /**
     * 传统价格模式分页查询
     *
     * @param page
     * @return
     */
    @Override
    public Page<PsupTraditionPriceVO> querySdTraditionPricePage(Page<PsupTraditionPrice> page) {
        log.info("PsupTraditionPriceServiceImpl.querySdTraditionPricePage param: {}", page);
        EntityWrapper<PsupTraditionPrice> ew = this.buildCondition(page.getCondition());
        List<PsupTraditionPrice> traditionPriceList = baseMapper.selectPage(page, ew);

        Page<PsupTraditionPriceVO> voPage = new Page<>();
        BeanUtils.copyProperties(page, voPage);
        if (CollectionUtils.isNotEmpty(traditionPriceList)) {
            List<PsupTraditionPriceVO> voList = Lists.newArrayList();
            traditionPriceList.forEach(traditionPrice -> {
                PsupTraditionPriceVO vo = new PsupTraditionPriceVO();
                BeanUtils.copyProperties(traditionPrice, vo);
                voList.add(vo);
            });
            voPage.setRecords(voList);
        }
        return voPage;
    }

    /**
     * 传统价格模式条件查询
     *
     * @param condition
     * @return
     */
    @Override
    public List<PsupTraditionPriceVO> querySdTraditionPriceByCondition(Map<String, Object> condition) {
        EntityWrapper<PsupTraditionPrice> ew = this.buildCondition(condition);
        List<PsupTraditionPrice> psupTraditionPriceList = this.selectList(ew);
        if (CollectionUtils.isNotEmpty(psupTraditionPriceList)) {
            List<PsupTraditionPriceVO> voList = Lists.newArrayList();
            psupTraditionPriceList.forEach(traditionPrice -> {
                PsupTraditionPriceVO vo = new PsupTraditionPriceVO();
                BeanUtils.copyProperties(traditionPrice, vo);
                // 生效时间
                if (Objects.nonNull(traditionPrice.getEffectiveDate())) {
                    vo.setEffectiveDateStr(new DateTime(traditionPrice.getEffectiveDate()).toString(ToolCommonUtils.yyyyMMdd));
                }
                // 失效时间
                if (Objects.nonNull(traditionPrice.getInvalidDate())) {
                    vo.setInvalidDateStr(new DateTime(traditionPrice.getInvalidDate()).toString(ToolCommonUtils.yyyyMMdd));
                }
                if (Objects.nonNull(traditionPrice.getStatus())) {
                    vo.setStatusStr(SdCommonEnum.getStatusValue(traditionPrice.getStatus()));
                }
                voList.add(vo);
            });
            return voList;
        }
        return null;
    }

    /**
     * 针对excel的导入的批量新增
     *
     * @param traditionPriceVOList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> createBatchTraditionPriceForExcel(List<PsupTraditionPriceVO> traditionPriceVOList, String token) {
        if (CollectionUtils.isNotEmpty(traditionPriceVOList)) {
            List<String> resultMsgList = verifyInsertParam(traditionPriceVOList, token);
            if (CollectionUtils.isNotEmpty(resultMsgList)) {
                return resultMsgList;
            }
            List<PsupTraditionPrice> insertTraditionPriceList = Lists.newArrayList();
            JwtAccountVO jwtAccount = AccountUtil.getAccountInfoFromSecurityContext();
            traditionPriceVOList.forEach(traditionPriceVo -> {
                PsupTraditionPrice insertTraditionPrice = new PsupTraditionPrice();
                BeanUtils.copyProperties(traditionPriceVo, insertTraditionPrice);
                insertTraditionPrice.setStatus(SdCommonEnum.NEW.getCode());
                insertTraditionPrice.setGmtCreate(new Date());
                insertTraditionPrice.setCreator(Long.valueOf(jwtAccount.getAccountId()));
                // 2019-10-30 创建人/上传人
                insertTraditionPrice.setCreatorName(jwtAccount.getUsername());
                insertTraditionPriceList.add(insertTraditionPrice);
            });
            if (CollectionUtils.isNotEmpty(insertTraditionPriceList)) {
                this.insertBatch(insertTraditionPriceList);
            }
        }
        return null;
    }

    /**
     * 审核
     *
     * @param idList
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<String> auditTraditionPrice(List<Long> idList) {
        List<String> resultMsgList = Lists.newArrayList();
        List<PsupTraditionPrice> updateTraditioPriceList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(idList)) {
            EntityWrapper<PsupTraditionPrice> ew = new EntityWrapper<>();
            ew.in("id", idList);
            ew.ne("status", SdCommonEnum.NEW.getCode());
            int count = this.selectCount(ew);
            if (count > 0) {
                throw new BaseException("存在非新增状态的数据, 不可审核!");
            } else {
                // 校验是否冲突
                List<PsupTraditionPrice> psupTraditionPriceList = this.selectBatchIds(idList);
                if (CollectionUtils.isNotEmpty(psupTraditionPriceList)) {
                    JwtAccountVO account = AccountUtil.getAccountInfoFromSecurityContext();
                    psupTraditionPriceList.forEach(traditionPrice -> {
                        StringBuilder sb = new StringBuilder();
                        if (traditionPrice.getPrice().compareTo(BigDecimal.TEN) > 0) {
                            sb.append("数据:").append("车队-").append(traditionPrice.getFleetName()).append(":单价大于10");
                            resultMsgList.add(sb.toString());
                        } else {
                            Integer countByFleet = getCountByFleet(traditionPrice);
                            if (countByFleet > 0) {
                                sb.append("数据:").append("车队-").append(traditionPrice.getFleetName()).append(":线路有效期冲突");
                                resultMsgList.add(sb.toString());
                            } else {
                                // 2019-10-30 审核人
                                traditionPrice.setActivitiName(account.getUsername());
                                traditionPrice.setStatus(SdCommonEnum.AUDIT.getCode());
                                updateTraditioPriceList.add(traditionPrice);
                            }
                        }
                    });
                }
                if (CollectionUtils.isNotEmpty(resultMsgList)) {
                    return resultMsgList;
                }
                if (CollectionUtils.isNotEmpty(updateTraditioPriceList)) {
                    this.updateBatchById(updateTraditioPriceList);
                }
            }
        }
        return null;
    }

    /**
     * 获取是否存在的数量
     *
     * @param psupPath
     * @return
     */
    private Integer getCountByFleet(PsupTraditionPrice psupPath) {
        Map<String, Object> condition = Maps.newHashMap();
        if (Objects.nonNull(psupPath.getEffectiveDate())) {
            condition.put("effectiveDate", new DateTime(psupPath.getEffectiveDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        if (Objects.nonNull(psupPath.getInvalidDate())) {
            condition.put("invalidDate", new DateTime(psupPath.getInvalidDate()).toString(ToolCommonUtils.yyyyMMdd));
        }
        condition.put("fleetId", psupPath.getFleetId());
        condition.put("notEqId", psupPath.getId());
        condition.put("status", SdCommonEnum.AUDIT.getCode());
        // 合同车型
        condition.put("contractVehicle", psupPath.getContractVehicle());
        // 起运/目的 省市区
        condition.put("startProvince", psupPath.getStartProvince());
        condition.put("startCity", psupPath.getStartCity());
        condition.put("startCounty", psupPath.getStartCounty());
        condition.put("startName", psupPath.getStartName());
        condition.put("endProvince", psupPath.getEndProvince());
        condition.put("endCity", psupPath.getEndCity());
        condition.put("endCounty", psupPath.getEndCounty());
        condition.put("endName", psupPath.getEndName());
        return baseMapper.verifyIsExistDate(condition);
    }

    /**
     * 批量删除
     *
     * @param idList
     * @return
     */
    @Override
    public List<String> deleteBatchByIdList(List<Long> idList) {
        if (CollectionUtils.isNotEmpty(idList)) {
            EntityWrapper<PsupTraditionPrice> ew = new EntityWrapper<>();
            ew.in("id", idList);
            ew.ne("status", SdCommonEnum.NEW.getCode());
            int count = this.selectCount(ew);
            if (count > 0) {
                throw new BaseException("存在非新增状态的数据, 不可删除!");
            } else {
                this.deleteBatchIds(idList);
            }
        }
        return null;
    }

    /**
     * 修改
     *
     * @param psupTraditionPriceVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateTraditionPice(PsupTraditionPriceVO psupTraditionPriceVO) {
        if (Objects.nonNull(psupTraditionPriceVO) && Objects.nonNull(psupTraditionPriceVO.getId())) {
            if (Objects.isNull(psupTraditionPriceVO.getEffectiveDate())) {
                throw new BaseException("生效日期为空!");
            }
            if (Objects.isNull(psupTraditionPriceVO.getInvalidDate())) {
                throw new BaseException("失效日期为空!");
            }
            if (StringUtils.isBlank(psupTraditionPriceVO.getFleetName())) {
                throw new BaseException("车队名称为空!");
            }
            if (Objects.isNull(psupTraditionPriceVO.getPrice())) {
                throw new BaseException("价格为空!");
            }
            if (Objects.isNull(psupTraditionPriceVO.getMileage())) {
                throw new BaseException("公里数为空!");
            }
            PsupTraditionPrice insertTraditionPrice = new PsupTraditionPrice();
            BeanUtils.copyProperties(psupTraditionPriceVO, insertTraditionPrice);
            cleanBlankCloumn(insertTraditionPrice);
            this.updateAllColumnById(insertTraditionPrice);
        }
    }

    /**
     * 清空数据
     *
     * @param insertTraditionPrice
     */
    private void cleanBlankCloumn(PsupTraditionPrice insertTraditionPrice) {
        if (StringUtils.isBlank(insertTraditionPrice.getStartProvince())) {
            insertTraditionPrice.setStartProvince(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getStartCity())) {
            insertTraditionPrice.setStartCity(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getStartCounty())) {
            insertTraditionPrice.setStartCounty(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getStartName())) {
            insertTraditionPrice.setStartName(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getEndProvince())) {
            insertTraditionPrice.setEndProvince(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getEndCity())) {
            insertTraditionPrice.setEndCity(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getEndCounty())) {
            insertTraditionPrice.setEndCounty(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getEndName())) {
            insertTraditionPrice.setEndName(null);
        }
        if (StringUtils.isBlank(insertTraditionPrice.getContractVehicle())) {
            insertTraditionPrice.setContractVehicle(null);
        }
    }

    /**
     * 查询条件
     *
     * @param condition
     * @return
     */
    private EntityWrapper<PsupTraditionPrice> buildCondition(Map<String, Object> condition) {
        EntityWrapper<PsupTraditionPrice> ew = new EntityWrapper<>();
        ew.orderBy("id desc");
        if (Objects.nonNull(condition)) {
            // 车队
            Object fleetId = condition.get("fleetId");
            if (Objects.nonNull(fleetId) && StringUtils.isNotBlank(fleetId.toString())) {
                ew.eq("fleet_id", fleetId);
            }
            // 车队名称
            Object fleetName = condition.get("fleetName");
            if (Objects.nonNull(fleetName) && StringUtils.isNotBlank(fleetName.toString())) {
                ew.like("fleet_name", fleetName.toString());
            }
            // 状态
            Object status = condition.get("status");
            if (Objects.nonNull(status) && StringUtils.isNotBlank(status.toString())) {
                ew.eq("status", status);
            }
            Object effectiveDateObj = condition.get("effectiveDate");
            if (Objects.nonNull(effectiveDateObj) && StringUtils.isNotBlank(effectiveDateObj.toString())) {
                Date effectiveDate = ToolCommonUtils.getDateByStr(effectiveDateObj.toString(), ToolCommonUtils.yyyyMMdd);
                ew.le("effective_date", effectiveDate);
                ew.ge("invalid_date", effectiveDate);
            }
            // 起运区
            startAndEndInfo(condition, ew, "startCounty", "start_county");
            // 起运名称
            startAndEndInfo(condition, ew, "startName", "start_name");
            // 目的省
            startAndEndInfo(condition, ew, "endProvince", "end_province");
            // 目的市
            startAndEndInfo(condition, ew, "endCity", "end_city");
            // 目的区
            startAndEndInfo(condition, ew, "endCounty", "end_county");
            // 目的名称
            startAndEndInfo(condition, ew, "endName", "end_name");
            // 合同车型名称
            startAndEndInfo(condition, ew, "contractVehicle", "contract_vehicle");
        }
        return ew;
    }

    private void startAndEndInfo(Map<String, Object> condition, EntityWrapper ew, String key, String column) {
        // 车队名称
        Object value = condition.get(key);
        if (Objects.nonNull(value) && StringUtils.isNotBlank(value.toString())) {
            ew.like(column, value.toString());
        }
    }

    /**
     * 校验数据并获取车队id
     *
     * @param voList
     * @param token
     * @return
     */
    private List<String> verifyInsertParam(List<PsupTraditionPriceVO> voList, String token) {
        Map<String, Long> fleetMap = getFleetMap(voList, token);
        if (Objects.nonNull(fleetMap)) {
            voList.stream()
                    .filter(traditionPrice -> StringUtils.isNotBlank(traditionPrice.getFleetName()))
                    .forEach(traditionPrice -> {
                        Long fleetId = fleetMap.get(traditionPrice.getFleetName());
                        if (Objects.nonNull(fleetId)) {
                            traditionPrice.setFleetId(fleetId);
                        }
                    });
        }
        List<String> resultMsgList = Lists.newArrayList();
        for (int i = 0, n = voList.size(); i < n; i++) {
            PsupTraditionPriceVO traditionPrice = voList.get(i);
            StringBuilder sb = new StringBuilder();
            if (StringUtils.isBlank(sb) && Objects.isNull(traditionPrice.getEffectiveDate())) {
                sb.append("生效日期为空!");
            }
            if (StringUtils.isBlank(sb) && Objects.isNull(traditionPrice.getInvalidDate())) {
                sb.append("失效日期为空!");
            }
            if (StringUtils.isBlank(sb) && StringUtils.isBlank(traditionPrice.getFleetName())) {
                sb.append("车队名称为空!");
            }
            if (StringUtils.isBlank(sb) && Objects.isNull(traditionPrice.getPrice())) {
                sb.append("价格为空!");
            }
            if (StringUtils.isBlank(sb) && Objects.isNull(traditionPrice.getMileage())) {
                sb.append("公里数为空!");
            }
            if (StringUtils.isNotBlank(sb)) {
                sb.insert(0, "行数:第" + (i + 1) + "行:");
                resultMsgList.add(sb.toString());
            }
        }
        return resultMsgList;
    }

    /**
     * 查询车队信息
     *
     * @param traditionPriceList
     * @param token
     * @return
     */
    private Map<String, Long> getFleetMap(List<PsupTraditionPriceVO> traditionPriceList, String token) {
        List<LspFleetDTO> dtoList = Lists.newArrayList();
        traditionPriceList.stream()
                .filter(traditionPrice -> StringUtils.isNotBlank(traditionPrice.getFleetName()))
                .forEach(traditionPrice -> {
                    LspFleetDTO lspFleetDTO = new LspFleetDTO();
                    lspFleetDTO.setFleetName(traditionPrice.getFleetName());
                    dtoList.add(lspFleetDTO);
                });
        List<LspFleetDTO> fleetList = lspUtil.getFleetAll(dtoList, token);
        if (CollectionUtils.isNotEmpty(fleetList)) {
            Map<String, Long> fleetMap = Maps.newHashMap();
            fleetList.forEach(fleet -> {
                fleetMap.put(fleet.getFleetName(), fleet.getId());
            });
            return fleetMap;
        }
        return null;
    }
}
